package com.joker.demo.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.joker.demo.admin.domain.dto.ExecutorRuntimeQueryDTO;
import com.joker.demo.admin.domain.po.ExecutorStatusPO;
import com.joker.demo.admin.domain.vo.AppStatisticsVO;
import com.joker.demo.admin.domain.vo.ExecutorRuntimeOverviewVO;
import com.joker.demo.admin.domain.vo.ExecutorRuntimeVO;
import com.joker.demo.admin.domain.vo.ExecutorStatusStatistics;
import com.joker.demo.admin.domain.vo.OnlineExecutorTrendVO;
import com.joker.demo.admin.domain.vo.PageResult;
import com.joker.demo.admin.mapper.ExecutorStatusMapper;
import com.joker.demo.admin.mapper.EnvironmentMonitorMapper;
import com.joker.demo.admin.service.ExecutorRuntimeService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 执行器运行情况Service实现类
 *
 * @author : feixiang.li
 * @since : 2025-01-27 10:00
 */
@Slf4j
@Service
public class ExecutorRuntimeServiceImpl implements ExecutorRuntimeService {

    @Resource
    private ExecutorStatusMapper executorStatusMapper;

    @Resource
    private EnvironmentMonitorMapper environmentMonitorMapper;

    @Override
    public ExecutorRuntimeOverviewVO getRuntimeOverview() {
        try {
            ExecutorRuntimeOverviewVO overview = new ExecutorRuntimeOverviewVO();

            // 查询所有执行器状态（只查询最近24小时有活动的执行器）
            LocalDateTime startTime = LocalDateTime.now().minusHours(24);
            LambdaQueryWrapper<ExecutorStatusPO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.ge(ExecutorStatusPO::getLastHeartbeatTime, startTime);
            List<ExecutorStatusPO> allExecutors = executorStatusMapper.selectList(queryWrapper);
            
            // 计算基础统计信息
            int totalExecutors = allExecutors.size();
            int onlineExecutors = (int) allExecutors.stream()
                    .filter(e -> "ONLINE".equals(e.getStatus()))
                    .count();
            int offlineExecutors = totalExecutors - onlineExecutors;

            // 计算健康状态分布
            int healthyCount = 0, warningCount = 0, errorCount = 0;
            int totalActiveThreads = 0, totalRunningTasks = 0;
            BigDecimal totalMemoryUsage = BigDecimal.ZERO;
            BigDecimal totalQueueUsage = BigDecimal.ZERO;
            int validMemoryCount = 0, validQueueCount = 0;

            for (ExecutorStatusPO executor : allExecutors) {
                // 计算健康状态
                String healthStatus = calculateHealthStatus(executor);
                switch (healthStatus) {
                    case "健康":
                        healthyCount++;
                        break;
                    case "警告":
                        warningCount++;
                        break;
                    case "异常":
                        errorCount++;
                        break;
                }

                // 累计统计数据
                if (executor.getCurrentActiveCount() != null) {
                    totalActiveThreads += executor.getCurrentActiveCount();
                }
                if (executor.getCurrentRunningTasks() != null) {
                    totalRunningTasks += executor.getCurrentRunningTasks();
                }
                if (executor.getCurrentMemoryUsagePercent() != null) {
                    totalMemoryUsage = totalMemoryUsage.add(executor.getCurrentMemoryUsagePercent());
                    validMemoryCount++;
                }
                if (executor.getCurrentQueueSize() != null && executor.getCurrentPoolSize() != null) {
                    // 这里简化计算队列使用率，实际可能需要更复杂的逻辑
                    validQueueCount++;
                }
            }

            // 设置概览信息
            overview.setTotalExecutors(totalExecutors);
            overview.setOnlineExecutors(onlineExecutors);
            overview.setOfflineExecutors(offlineExecutors);
            overview.setHealthyExecutors(healthyCount);
            overview.setWarningExecutors(warningCount);
            overview.setErrorExecutors(errorCount);
            overview.setTotalActiveThreads(totalActiveThreads);
            overview.setTotalRunningTasks(totalRunningTasks);

            // 计算平均值
            if (validMemoryCount > 0) {
                overview.setAverageMemoryUsage(totalMemoryUsage.divide(BigDecimal.valueOf(validMemoryCount), 2, RoundingMode.HALF_UP));
            } else {
                overview.setAverageMemoryUsage(BigDecimal.ZERO);
            }

            // 设置状态分布
            List<ExecutorStatusStatistics> statusDistribution = new ArrayList<>();
            ExecutorStatusStatistics normalStats = new ExecutorStatusStatistics();
            normalStats.setNormalCount(healthyCount);
            normalStats.setWarningCount(warningCount);
            normalStats.setErrorCount(errorCount);
            normalStats.setOfflineCount(offlineExecutors);
            statusDistribution.add(normalStats);
            overview.setStatusDistribution(statusDistribution);

            // 设置应用分布
            Map<String, Long> appCounts = allExecutors.stream()
                    .collect(Collectors.groupingBy(ExecutorStatusPO::getAppName, Collectors.counting()));
            
            List<AppStatisticsVO> appDistribution = appCounts.entrySet().stream()
                    .map(entry -> {
                        AppStatisticsVO appStats = new AppStatisticsVO();
                        appStats.setAppName(entry.getKey());
                        appStats.setExecutorCount(entry.getValue().intValue());
                        return appStats;
                    })
                    .collect(Collectors.toList());
            overview.setAppDistribution(appDistribution);

            // 设置最近活跃的执行器
            List<ExecutorRuntimeVO> recentActiveExecutors = allExecutors.stream()
                    .filter(e -> e.getLastHeartbeatTime() != null)
                    .sorted((e1, e2) -> e2.getLastHeartbeatTime().compareTo(e1.getLastHeartbeatTime()))
                    .limit(10)
                    .map(this::convertToRuntimeVO)
                    .collect(Collectors.toList());
            overview.setRecentActiveExecutors(recentActiveExecutors);

            return overview;

        } catch (Exception e) {
            log.error("获取执行器运行情况概览失败", e);
            throw new RuntimeException("获取执行器运行情况概览失败", e);
        }
    }

    @Override
    public PageResult<ExecutorRuntimeVO> queryExecutorRuntime(ExecutorRuntimeQueryDTO queryDTO) {
        try {
            // 构建查询条件
            LambdaQueryWrapper<ExecutorStatusPO> queryWrapper = new LambdaQueryWrapper<>();
            
            if (StringUtils.hasText(queryDTO.getRegisterKey())) {
                queryWrapper.like(ExecutorStatusPO::getRegisterKey, queryDTO.getRegisterKey());
            }
            if (StringUtils.hasText(queryDTO.getAppName())) {
                queryWrapper.eq(ExecutorStatusPO::getAppName, queryDTO.getAppName());
            }
            if (StringUtils.hasText(queryDTO.getStatus())) {
                queryWrapper.eq(ExecutorStatusPO::getStatus, queryDTO.getStatus());
            }
            if (queryDTO.getStartTime() != null) {
                queryWrapper.ge(ExecutorStatusPO::getLastHeartbeatTime, queryDTO.getStartTime());
            }
            if (queryDTO.getEndTime() != null) {
                queryWrapper.le(ExecutorStatusPO::getLastHeartbeatTime, queryDTO.getEndTime());
            }
            
            // 按最后心跳时间倒序排列
            queryWrapper.orderByDesc(ExecutorStatusPO::getLastHeartbeatTime);

            // 分页查询
            Page<ExecutorStatusPO> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
            IPage<ExecutorStatusPO> result = executorStatusMapper.selectPage(page, queryWrapper);

            // 转换为VO
            List<ExecutorRuntimeVO> voList = result.getRecords().stream()
                    .map(this::convertToRuntimeVO)
                    .collect(Collectors.toList());

            // 构建分页结果
            PageResult<ExecutorRuntimeVO> pageResult = new PageResult<>();
            pageResult.setRecords(voList);
            pageResult.setTotal(result.getTotal());
            pageResult.setCurrent((long) queryDTO.getPageNum());
            pageResult.setSize((long) queryDTO.getPageSize());

            return pageResult;

        } catch (Exception e) {
            log.error("查询执行器运行情况失败", e);
            throw new RuntimeException("查询执行器运行情况失败", e);
        }
    }

    @Override
    public ExecutorRuntimeVO getExecutorRuntime(String registerKey) {
        try {
            LambdaQueryWrapper<ExecutorStatusPO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ExecutorStatusPO::getRegisterKey, registerKey);
            
            ExecutorStatusPO executorStatus = executorStatusMapper.selectOne(queryWrapper);
            if (executorStatus == null) {
                return null;
            }
            
            return convertToRuntimeVO(executorStatus);
        } catch (Exception e) {
            log.error("查询执行器运行情况失败: {}", registerKey, e);
            throw new RuntimeException("查询执行器运行情况失败", e);
        }
    }

    @Override
    public List<ExecutorRuntimeVO> getAllExecutorRuntime() {
        try {
            // 只查询最近24小时有活动的执行器
            LocalDateTime startTime = LocalDateTime.now().minusHours(24);
            LambdaQueryWrapper<ExecutorStatusPO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.ge(ExecutorStatusPO::getLastHeartbeatTime, startTime);
            queryWrapper.orderByDesc(ExecutorStatusPO::getLastHeartbeatTime);
            
            List<ExecutorStatusPO> allExecutors = executorStatusMapper.selectList(queryWrapper);
            return allExecutors.stream()
                    .map(this::convertToRuntimeVO)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("查询所有执行器运行情况失败", e);
            throw new RuntimeException("查询所有执行器运行情况失败", e);
        }
    }

    @Override
    public List<ExecutorRuntimeVO> getOnlineExecutors() {
        try {
            LambdaQueryWrapper<ExecutorStatusPO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ExecutorStatusPO::getStatus, "ONLINE");
            
            List<ExecutorStatusPO> onlineExecutors = executorStatusMapper.selectList(queryWrapper);
            return onlineExecutors.stream()
                    .map(this::convertToRuntimeVO)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("查询在线执行器失败", e);
            throw new RuntimeException("查询在线执行器失败", e);
        }
    }

    @Override
    public List<ExecutorRuntimeVO> getOfflineExecutors() {
        try {
            LambdaQueryWrapper<ExecutorStatusPO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ExecutorStatusPO::getStatus, "OFFLINE");
            
            List<ExecutorStatusPO> offlineExecutors = executorStatusMapper.selectList(queryWrapper);
            return offlineExecutors.stream()
                    .map(this::convertToRuntimeVO)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("查询离线执行器失败", e);
            throw new RuntimeException("查询离线执行器失败", e);
        }
    }

    @Override
    public void updateExecutorStatus(ExecutorStatusPO executorStatus) {
        try {
            if (executorStatus == null) {
                log.warn("执行器状态为空，跳过更新");
                return;
            }

            // 设置更新时间
            executorStatus.setUpdateTime(LocalDateTime.now());

            // 检查是否已存在
            LambdaQueryWrapper<ExecutorStatusPO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ExecutorStatusPO::getRegisterKey, executorStatus.getRegisterKey());
            
            ExecutorStatusPO existingStatus = executorStatusMapper.selectOne(queryWrapper);
            if (existingStatus != null) {
                // 更新
                executorStatus.setId(existingStatus.getId());
                executorStatusMapper.updateById(executorStatus);
            } else {
                // 新增
                executorStatus.setCreateTime(LocalDateTime.now());
                executorStatusMapper.insert(executorStatus);
            }

            log.debug("执行器状态更新成功: {}", executorStatus.getRegisterKey());
        } catch (Exception e) {
            log.error("更新执行器状态失败: {}", executorStatus != null ? executorStatus.getRegisterKey() : "null", e);
            throw new RuntimeException("更新执行器状态失败", e);
        }
    }

    @Override
    public void cleanOfflineExecutors(Integer timeoutMinutes) {
        try {
            if (timeoutMinutes == null || timeoutMinutes <= 0) {
                log.warn("清理离线执行器参数无效，timeoutMinutes：{}", timeoutMinutes);
                return;
            }

            // 计算超时时间点
            LocalDateTime timeoutTime = LocalDateTime.now().minusMinutes(timeoutMinutes);
            
            // 构建删除条件
            LambdaQueryWrapper<ExecutorStatusPO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ExecutorStatusPO::getStatus, "OFFLINE");
            queryWrapper.lt(ExecutorStatusPO::getLastHeartbeatTime, timeoutTime);
            
            // 执行删除
            int deletedCount = executorStatusMapper.delete(queryWrapper);
            
            log.info("离线执行器清理完成，清理 {} 分钟前离线执行器，删除记录数：{}", timeoutMinutes, deletedCount);
        } catch (Exception e) {
            log.error("清理离线执行器失败", e);
            throw new RuntimeException("清理离线执行器失败", e);
        }
    }

    /**
     * 将PO转换为VO
     */
    private ExecutorRuntimeVO convertToRuntimeVO(ExecutorStatusPO executorStatus) {
        ExecutorRuntimeVO vo = new ExecutorRuntimeVO();
        vo.setRegisterKey(executorStatus.getRegisterKey());
        vo.setAppName(executorStatus.getAppName());
        vo.setLastHeartbeatTime(executorStatus.getLastHeartbeatTime());
        vo.setLastMonitorTime(executorStatus.getLastMonitorTime());
        vo.setStatus(executorStatus.getStatus());
        vo.setStatusDesc(getStatusDesc(executorStatus.getStatus()));
        vo.setCurrentPoolSize(executorStatus.getCurrentPoolSize());
        vo.setCurrentActiveCount(executorStatus.getCurrentActiveCount());
        vo.setCurrentQueueSize(executorStatus.getCurrentQueueSize());
        vo.setCurrentMemoryUsagePercent(executorStatus.getCurrentMemoryUsagePercent());
        vo.setCurrentRunningTasks(executorStatus.getCurrentRunningTasks());
        
        // 计算运行时长
        if (executorStatus.getLastHeartbeatTime() != null) {
            long uptimeSeconds = java.time.Duration.between(executorStatus.getLastHeartbeatTime(), LocalDateTime.now()).getSeconds();
            vo.setUptimeSeconds(uptimeSeconds);
        }
        
        // 设置在线状态
        vo.setIsOnline("ONLINE".equals(executorStatus.getStatus()));
        
        // 设置健康状态
        String healthStatus = calculateHealthStatus(executorStatus);
        vo.setHealthStatus(healthStatus);
        vo.setHealthStatusDesc(getHealthStatusDesc(healthStatus));
        
        return vo;
    }

    /**
     * 获取状态描述
     */
    private String getStatusDesc(String status) {
        if ("ONLINE".equals(status)) {
            return "在线";
        } else if ("OFFLINE".equals(status)) {
            return "离线";
        } else {
            return "未知";
        }
    }

    /**
     * 计算健康状态
     */
    private String calculateHealthStatus(ExecutorStatusPO executorStatus) {
        if (!"ONLINE".equals(executorStatus.getStatus())) {
            return "异常";
        }

        // 检查内存使用率
        if (executorStatus.getCurrentMemoryUsagePercent() != null) {
            if (executorStatus.getCurrentMemoryUsagePercent().compareTo(BigDecimal.valueOf(90)) > 0) {
                return "异常";
            } else if (executorStatus.getCurrentMemoryUsagePercent().compareTo(BigDecimal.valueOf(80)) > 0) {
                return "警告";
            }
        }

        // 检查队列使用率
        if (executorStatus.getCurrentQueueSize() != null && executorStatus.getCurrentPoolSize() != null) {
            double queueUsage = (double) executorStatus.getCurrentQueueSize() / executorStatus.getCurrentPoolSize();
            if (queueUsage > 0.9) {
                return "异常";
            } else if (queueUsage > 0.7) {
                return "警告";
            }
        }

        return "健康";
    }

    /**
     * 获取健康状态描述
     */
    private String getHealthStatusDesc(String healthStatus) {
        switch (healthStatus) {
            case "健康":
                return "执行器运行正常";
            case "警告":
                return "执行器资源使用率较高";
            case "异常":
                return "执行器资源使用率过高或离线";
            default:
                return "未知状态";
        }
    }

    @Override
    public OnlineExecutorTrendVO queryOnlineExecutorTrend() {
        try {
            OnlineExecutorTrendVO result = new OnlineExecutorTrendVO();
            
            // 计算24小时前的时间
            LocalDateTime endTime = LocalDateTime.now();
            LocalDateTime startTime = endTime.minusHours(24);
            
            // 查询24小时内的环境监控数据，按小时分组统计在线执行器数量
            List<OnlineExecutorTrendVO.OnlineExecutorTrendItem> trendData = new ArrayList<>();
            
            // 生成24个小时的数据点
            for (int hour = 0; hour < 24; hour++) {
                LocalDateTime hourStart = startTime.plusHours(hour);
                LocalDateTime hourEnd = hourStart.plusHours(1);
                
                OnlineExecutorTrendVO.OnlineExecutorTrendItem item = new OnlineExecutorTrendVO.OnlineExecutorTrendItem();
                item.setHour(hour);
                item.setTimePoint(String.format("%02d:00", hour));
                
                // 查询该小时内的执行器数据
                int totalCount = environmentMonitorMapper.countExecutorsByHour(hourStart, hourEnd);
                int onlineCount = environmentMonitorMapper.countOnlineExecutorsByHour(hourStart, hourEnd);
                int offlineCount = totalCount - onlineCount;
                
                item.setTotalCount(totalCount);
                item.setOnlineCount(onlineCount);
                item.setOfflineCount(offlineCount);
                
                // 计算在线率
                if (totalCount > 0) {
                    item.setOnlineRate((double) onlineCount / totalCount * 100);
                } else {
                    item.setOnlineRate(0.0);
                }
                
                trendData.add(item);
            }
            
            result.setTrendData(trendData);
            return result;
            
        } catch (Exception e) {
            log.error("查询在线执行器趋势失败", e);
            throw new RuntimeException("查询在线执行器趋势失败", e);
        }
    }
}
